using System.Diagnostics;
using System.Text;
using BLL.Manager;
using Helper;
using HZY.Framework.DependencyInjection;
using IoTClient.Common.Enums;
using IoTClient.Enums;
using Microsoft.EntityFrameworkCore.ChangeTracking.Internal;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using MiniExcelLibs;
using Model.EntityInfo;
using Sunny.UI;
using WinFormsSprayProcessSCADASystem.Extension;
using WinFormsSprayProcessSCADASystem.Pages;

namespace WinFormsSprayProcessSCADASystem
{
    public partial class MainForm : UIHeaderAsideMainFooterFrame, IScopedSelfDependency
    {
        #region 成员变量
        private NotifyIcon notifyIcon = new NotifyIcon();

        private bool _plcIsConnect = false;

        private CancellationTokenSource _cts = new CancellationTokenSource();

        //页面Dictionary
        private readonly Dictionary<string, UIPage> _pageMap = new Dictionary<string, UIPage>();
        //Webview页面Dictionary
        private readonly Dictionary<int, RouteInfoModel> _webViewMap = new Dictionary<int, RouteInfoModel>();


        //主题变化回调
        public event Action<string> ThemeCahnge;
        public event Action PlcValCahnge;


        private readonly DataLogManager _dataLogManager;
        //public static UIWaitForm loadingForm = new UIWaitForm("系统加载中...");
        #endregion

        #region 生命周期
        public MainForm(DataLogManager dataLogManager)
        {
            InitializeComponent();
            UserLoadForm loadingForm = new UserLoadForm();
            loadingForm.Name = "load_form";
            loadingForm.Location = new Point(0, 0);
            loadingForm.Size = this.Size;
            this.Controls.Add(loadingForm);

            this._dataLogManager = dataLogManager;
            this.Load += MainForm_Load;
            this.Activated += MainForm_Activated;
            this.Shown += MainForm_Shown;
            this.Closed += MainForm_Closed;
        }

        private void MainForm_Activated(object? sender, EventArgs e)
        {

        }

        private void MainForm_Load(object? sender, EventArgs e)
        {
            notifyIcon.Visible = true;
            UIEXtension.SetStyleManager?.Invoke(uiStyleManager1);
            this.Opacity = 0;

            _pageMap.Add("PageTotalEquipmentControl", Globals.ServiceProvider.GetRequiredService<PageTotalEquipmentControl>());
            _pageMap.Add("PageUserManage", Globals.ServiceProvider.GetRequiredService<PageUserManage>());
            _pageMap.Add("PageEquipmentMonitor", Globals.ServiceProvider.GetRequiredService<PageEquipmentMonitor>());
            _pageMap.Add("PageEquipmentMonitor1", Globals.ServiceProvider.GetRequiredService<PageEquipmentMonitor1>());
            _pageMap.Add("PageEquipmentMonitor2", Globals.ServiceProvider.GetRequiredService<PageEquipmentMonitor2>());
            _pageMap.Add("PageLogManage", Globals.ServiceProvider.GetRequiredService<PageLogManage2>());
            _pageMap.Add("PageReportManage", Globals.ServiceProvider.GetRequiredService<PageReportManage2>());
            _pageMap.Add("PageChartManage", Globals.ServiceProvider.GetRequiredService<PageChartManage2>());
            _pageMap.Add("PageSystemParameterSet", Globals.ServiceProvider.GetRequiredService<PageSystemParameterSet>());
            _pageMap.Add("PageWebView", Globals.ServiceProvider.GetRequiredService<PageWebView>());
        }


        private async void MainForm_Shown(object sender, EventArgs e)
        {
            Init();
            //Thread.Sleep(2000);
            //await Task.Delay(2000);

            this.Opacity = 100;
            Splasher.Status = "初始化完毕......";
            Splasher.Close();
        }
        public override void Init()
        {
            base.Init();


            //初始化配置
            Splasher.Status = "初始化配置......";

            //Thread.Sleep(1000);
            InitConfig();
            //初始化UI界面
            Splasher.Status = "初始化UI界面......";
            //Thread.Sleep(1000);
            InitPage();
            //初始化PLC客户端
            Splasher.Status = "初始化PLC客户端......";
            //Thread.Sleep(1000);
            InitPlcClient();


            timer1.Start();
        }
        #endregion

        #region 初始化配置
        private void InitConfig()
        {
            Globals.PlcVarConfigPath = Globals.IniFile.ReadString("PLC", "path", $"{Application.StartupPath}\\..\\config\\PlcVarConfig.xlsx");
            //CPU类型
            Globals.CpuType = Enum.Parse<SiemensVersion>(Globals.IniFile.ReadString("PLC", "siemensVersion", "S7_1200"));

            //ip地址
            Globals.IpAddress = Globals.IniFile.ReadString("PLC", "ipAddress", "127.0.0.1");

            //端口号
            Globals.Port = Globals.IniFile.ReadInt("PLC", "port", 102);

            //插槽
            Globals.Slot = Globals.IniFile.ReadByte("PLC", "slot", 0);

            //机架号
            Globals.Rack = Globals.IniFile.ReadByte("PLC", "rack", 0);

            //plc连接超时时间
            Globals.ConnectTimeOut = Globals.IniFile.ReadInt("PLC", "connectTimeOut", 2000);

            //plc读取间隔时间
            Globals.ReadTimeInnterval = Globals.IniFile.ReadInt("PLC", "readTimeInnterval", 2000);

            //plc重连间隔时间
            Globals.ReConnectTimeInnterval = Globals.IniFile.ReadInt("PLC", "reConnectTimeInnterval", 2000);
        }
        #endregion

        #region 初始化PLC客户端
        private void InitPlcClient()
        {

            Console.WriteLine(Globals.PlcVarConfigPath);
            List<PlcVarConfigModel> plcVarConfigModels = MiniExcel.Query<PlcVarConfigModel>(Globals.PlcVarConfigPath).ToList();


            for (int i = 0; i < plcVarConfigModels.Count; i++)
            {
                Globals.ReadDic.Add(plcVarConfigModels[i].plcAddress, Enum.Parse<DataTypeEnum>(plcVarConfigModels[i].varType, true));
                Globals.WriteDic.Add(plcVarConfigModels[i].name, plcVarConfigModels[i].plcAddress);
                Globals.DataDic.Add(plcVarConfigModels[i].name, "NA");
            }
            //初始化西门子客户端
            Globals.SiemensClient = new IoTClient.Clients.PLC.SiemensClient(Globals.CpuType, Globals.IpAddress, Globals.Port, Globals.Slot, Globals.Rack, Globals.ConnectTimeOut);

            //第一次尝试连接plc
            IoTClient.Result result = Globals.SiemensClient.Open();
            if (result.IsSucceed)
            {
                this._plcIsConnect = true;
                this.lb_plcStatus.On = true;
                this.LogMes("PLC连接成功！");
            }
            else
            {
                this._plcIsConnect = false;
                this.lb_plcStatus.On = false;
                this.LogError("第一次PLC连接失败！");
            }

            try
            {
                Task.Run(async () =>
                {
                    try
                    {

                        while (!_cts.IsCancellationRequested)
                        {
                            if (this._plcIsConnect)
                            {
                                Dictionary<string, DataTypeEnum> addresses = new Dictionary<string, DataTypeEnum>();
                                //IoTClient.Result<Dictionary<string, object>> result1 = Globals.SiemensClient.BatchRead(addresses);
                                IoTClient.Result<Dictionary<string, object>> result1 = Globals.SiemensClient.BatchRead(Globals.ReadDic);
                                if (result1.IsSucceed)
                                {
                                    for (int i = 0; i < plcVarConfigModels.Count; i++)
                                    {
                                        Globals.DataDic[plcVarConfigModels[i].name] = result1.Value[plcVarConfigModels[i].plcAddress];
                                    }

                                    UpdatePlcUi();
                                    await Task.Delay(Globals.ReadTimeInnterval);
                                }
                                else
                                {
                                    Globals.SiemensClient.Close();
                                    _plcIsConnect = false;
                                    this.Invoke(() =>
                                    {
                                        this.lb_plcStatus.On = false;
                                    });
                                }
                            }
                            else
                            {
                                //重连PLC
                                IoTClient.Result result = Globals.SiemensClient.Open();
                                if (result.IsSucceed)
                                {
                                    this._plcIsConnect = true;
                                    this.LogMes("PLC重新连接成功！");
                                    this.Invoke(() =>
                                    {
                                        this.lb_plcStatus.On = true;
                                    });
                                }
                                else
                                {
                                    _plcIsConnect = false;
                                    this.Invoke(() =>
                                    {
                                        this.lb_plcStatus.On = false;
                                    });

                                    this.LogError("PLC重新连接失败！");
                                    await Task.Delay(Globals.ReConnectTimeInnterval);
                                }
                            }

                        }

                    }
                    catch (OperationCanceledException)
                    {
                        this.LogMes("PLC 读取任务已取消！");
                    }
                    catch (Exception ex)
                    {
                        this.LogError($"PLC读取任务发生错误:{ex.Message}");

                        // 确保连接状态正确
                        this._plcIsConnect = false;
                        this.Invoke(() => { this.lb_plcStatus.On = false; });

                        // 等待一段时间后重试
                        await Task.Delay(Globals.ReConnectTimeInnterval);
                    }

                }, _cts.Token);
            }
            catch (Exception ex)
            {
                this.LogError($"{ex.Message}");
                throw;
            }
        }
        //更新PLC相关的UI;
        private void UpdatePlcUi()
        {
            try
            {

                PlcValCahnge?.Invoke();
                this.Invoke(() =>
                {
                    uiLedLabel1.Text = Globals.DataDic["生产计数"].ToString();
                    uiLedLabel2.Text = Globals.DataDic["不良计数"].ToString();
                    uiLedLabel3.Text = $"{Globals.DataDic["生产节拍"].ToString()} S";
                    uiLedLabel4.Text = Globals.DataDic["累计报警"].ToString();
                    uiLabel5.Text = Globals.DataDic["厂内温度"].ToString() + "℃";
                    uiLabel7.Text = Globals.DataDic["厂内湿度"].ToString() + "%";
                });

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

        }
        #endregion

        #region 初始化界面
        private void InitPage()
        {
            lUserRole.Text = Globals.CurrentUser.RoleInfo.Name;


            // 创建 NotifyIcon 控件
            notifyIcon.Icon = SystemIcons.Application; // 设置图标
            notifyIcon.Text = "应用程序已最小化到系统托盘"; // 设置提示信息
            notifyIcon.MouseClick += NotifyIcon_MouseClick; // 

            int pageIndex = 1000;

            CreateAsideNode(Globals.RouteList);

            //TreeNode parent = Aside.CreateNode("控制模块", 361461, 24, pageIndex);
            //Aside.CreateChildNode(parent, AddPage(Globals.ServiceProvider.GetRequiredService<PageTotalEquipmentControl>(), ++pageIndex));

            //pageIndex = 2000;
            //TreeNode parent = Aside.CreateNode("用户模块", 61451, 24, pageIndex);
            //Aside.CreateChildNode(parent, AddPage(Globals.ServiceProvider.GetRequiredService<PageUserManage>(), ++pageIndex));
            ////Aside.CreateChildNode(parent, AddPage(Globals.ServiceProvider.GetRequiredService<PageRoleManage>(), ++pageIndex));
            //Aside.CreateChildNode(parent, "角色列表", 261447, 24, ++pageIndex);//2002

            //pageIndex = 3000;
            //parent = Aside.CreateNode("监控模块", 61451, 24, pageIndex);
            //Aside.CreateChildNode(parent, AddPage(new PageEquipmentMonitor(), ++pageIndex));
            //Aside.CreateChildNode(parent, AddPage(new PageEquipmentMonitor1(), ++pageIndex));
            //Aside.CreateChildNode(parent, AddPage(new PageEquipmentMonitor2(), ++pageIndex));

            //pageIndex = 4000;
            //parent = Aside.CreateNode("配方模块", 61451, 24, pageIndex);
            ////Aside.CreateChildNode(parent, AddPage(new PageRecipeManage(), ++pageIndex));
            //Aside.CreateChildNode(parent, "配方管理", 162333, 24, ++pageIndex);//4001

            //pageIndex = 5000;
            //parent = Aside.CreateNode("日志模块", 61451, 24, pageIndex);
            //Aside.CreateChildNode(parent, AddPage(new PageLogManage(), ++pageIndex));

            //pageIndex = 6000;
            //parent = Aside.CreateNode("报表模块", 61451, 24, pageIndex);
            //Aside.CreateChildNode(parent, AddPage(new PageReportManage(), ++pageIndex));

            //pageIndex = 7000;
            //parent = Aside.CreateNode("图表模块", 61451, 24, pageIndex);
            //Aside.CreateChildNode(parent, AddPage(new PageChartManage(), ++pageIndex));

            //pageIndex = 8000;
            //parent = Aside.CreateNode("参数模块", 61451, 24, pageIndex);
            //Aside.CreateChildNode(parent, AddPage(new PageSystemParameterSet(), ++pageIndex));


            Aside.TabControl.AddPage(Globals.ServiceProvider.GetRequiredService<PageWebView>());
            if (Globals.RouteList.Count > 0)
            {
                Aside.SelectPage(Globals.RouteList[0].Id);
            }


            pageIndex = 9000;
            Header.Nodes.Add("主题");
            Header.SetNodePageIndex(Header.Nodes[0], pageIndex);
            Header.SetNodeSymbol(Header.Nodes[0], 61502);
            var styles = UIStyles.PopularStyles();
            foreach (UIStyle style in styles)
            {
                Header.CreateChildNode(Header.Nodes[0], style.Description(), style.Value());
            }

        }

        private void CreateAsideNode(List<RouteInfoModel> Routes, TreeNode parentNode = null)
        {
            foreach (var item in Routes)
            {
                if (parentNode == null)
                {
                    if (item.Children.Count == 0)
                    {
                        if (item.IsWebView)
                        {
                            _webViewMap.Add(item.Id, item);
                            Aside.CreateNode(item.Name, item.Icon, 24, item.Id);
                        }
                        else
                        {
                            if (_pageMap.TryGetValue(item.ClassName, out UIPage page))
                            {
                                var _node = Aside.CreateNode(page);
                                _node.Text = item.Name;
                            }
                            else
                            {
                                throw new Exception($"UIPage：{item.ClassName}未注册？");
                            }
                        }
                    }
                    else
                    {
                        TreeNode parent = Aside.CreateNode(item.Name, item.Icon, 24, item.Id);
                        CreateAsideNode(item.Children, parent);
                    }
                }
                else
                {
                    if (item.IsWebView)
                    {
                        _webViewMap.Add(item.Id, item);
                        Aside.CreateChildNode(parentNode, item.Name, item.Icon, 24, item.Id);//2002
                    }
                    else
                    {
                        if (_pageMap.TryGetValue(item.ClassName, out UIPage page))
                        {
                            Aside.CreateChildNode(parentNode, AddPage(page, item.Id));
                        }
                    }

                }
            }
        }

        private void Header_MenuItemClick(string itemText, int menuIndex, int pageIndex)
        {
            switch (menuIndex)
            {
                case 0:
                    UIStyle style = (UIStyle)pageIndex;
                    uiStyleManager1.Style = style;
                    UIEXtension.Style = style;
                    UIEXtension.SetStyleManager?.Invoke(uiStyleManager1);
                    ThemeCahnge?.Invoke(style.Description());
                    break;
                default:

                    break;
            }
        }

        private void Aside_MenuItemClick(TreeNode node, NavMenuItem item, int pageIndex)
        {
            if (_webViewMap.TryGetValue(pageIndex, out RouteInfoModel route))
            {
                Globals.ServiceProvider.GetRequiredService<PageWebView>().SwitchPage(route.ClassName);
                Aside.TabControl.SelectPage(6666);
            }
            //switch (pageIndex)
            //{
            //    case 2002:
            //        Globals.ServiceProvider.GetRequiredService<PageWebView>().SwitchPage("/roleManage");
            //        Aside.TabControl.SelectPage(6666);
            //        break;
            //    case 4001:
            //        Globals.ServiceProvider.GetRequiredService<PageWebView>().SwitchPage("/recipeManage");
            //        Aside.TabControl.SelectPage(6666);
            //        break;
            //}
        }
        private void NotifyIcon_MouseClick(object? sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                // 当点击系统托盘图标时，恢复窗口显示
                this.Show();
            }
        }


        protected override CreateParams CreateParams
        {
            get
            {
                CreateParams cp = base.CreateParams;
                cp.ExStyle |= 0x02000000;
                return cp;
            }
        }
        #endregion


        private void timer1_Tick(object sender, EventArgs e)
        {
            this.Invoke(() =>
            {
                uiLabel8.Text = DateTime.Now.DateTimeString();

                string CPUstr = RuntimeStatusHelper.DataManager.GetCpuUtilization();
                string MemoryStr = RuntimeStatusHelper.DataManager.GetMemoryUtilization().Replace("G", "");
                string NeiResult = (double.Parse(MemoryStr.Split('/')[0]) / double.Parse(MemoryStr.Split('/')[1]) * 100).ToString("f1") + "%";
                this.uiLabel16.Text = double.Parse(CPUstr).ToString("f1") + "%";
                this.uiLabel18.Text = NeiResult;

                #region 报警信息
                var alarmStr = new StringBuilder("");
                foreach (var item in Globals.DataDic)
                {
                    if (item.Key.EndsWith("报警") && !item.Key.Contains("累计") && item.Value.ToString() == "1")
                    {
                        alarmStr.Append(",");
                        alarmStr.Append(item.Key);
                    }
                }
                if (alarmStr.Length > 0)
                {
                    alarmStr.Remove(0, 1);
                    uiScrollingText1.Text = alarmStr.ToString();
                    if (!uiLedBulb1.Blink)
                    {
                        uiLedBulb1.Color = Color.Red;
                        uiLedBulb1.On = false;
                        uiLedBulb1.Blink = true;
                    }
                }
                else
                {
                    if (uiLedBulb1.Blink)
                    {
                        uiScrollingText1.Text = "系统正常";
                        uiLedBulb1.Color = Color.FromArgb(0xc0ffc0);
                        uiLedBulb1.On = true;
                        uiLedBulb1.Blink = false;
                    }
                }
                #endregion

                #region 更新ui
                try
                {

                    PlcValCahnge?.Invoke();
                    this.Invoke(() =>
                    {
                        uiLedLabel1.Text = (Globals.DataDic["生产计数"] ?? 0).ToString();
                        uiLedLabel2.Text = (Globals.DataDic["不良计数"] ?? 0).ToString();
                        uiLedLabel3.Text = $"{(Globals.DataDic["生产节拍"] ?? 0).ToString()} S";
                        uiLedLabel4.Text = (Globals.DataDic["累计报警"] ?? 0).ToString();
                        uiLabel5.Text = (Globals.DataDic["厂内温度"] ?? 25).ToString() + "℃";
                        uiLabel7.Text = (Globals.DataDic["厂内湿度"] ?? 50).ToString() + "%";
                    });

                }
                catch (Exception ex)
                {
                    this.LogError(ex.Message);
                }
                #endregion

                #region 运行数据记录
                _ = this._dataLogManager.CreateDataLogAsync(new BLL.DTO.DataDto.DataLogAddDto()
                {
                    脱脂喷淋泵压力值 = ToolHelper.GetValueOrDefault(Globals.DataDic, "脱脂喷淋泵压力值"),
                    脱脂pH值 = ToolHelper.GetValueOrDefault(Globals.DataDic, "脱脂pH值"),
                    陶化pH值 = ToolHelper.GetValueOrDefault(Globals.DataDic, "陶化pH值"),
                    粗洗喷淋泵压力值 = ToolHelper.GetValueOrDefault(Globals.DataDic, "粗洗喷淋泵压力值"),
                    陶化喷淋泵压力值 = ToolHelper.GetValueOrDefault(Globals.DataDic, "陶化喷淋泵压力值"),
                    精洗喷淋泵压力值 = ToolHelper.GetValueOrDefault(Globals.DataDic, "精洗喷淋泵压力值"),
                    水分炉测量温度 = ToolHelper.GetValueOrDefault(Globals.DataDic, "水分炉测量温度"),
                    固化炉测量温度 = ToolHelper.GetValueOrDefault(Globals.DataDic, "固化炉测量温度"),
                    厂内温度 = ToolHelper.GetValueOrDefault(Globals.DataDic, "厂内温度"),
                    厂内湿度 = ToolHelper.GetValueOrDefault(Globals.DataDic, "厂内湿度"),
                });
                #endregion
            });
        }
        private void MainForm_Closed(object? sender, EventArgs e)
        {
            Console.WriteLine("Closed");
            Globals.SiemensClient.Close();
            timer1?.Stop();
        }

        private void ExitBtn_Click(object sender, EventArgs e)
        {
            if (this.ShowAskDialog2("确认要退出当前账号吗？", true))
            {
                Globals.SiemensClient.Close();
                timer1?.Stop();
                Application.Exit();
                Process.Start(Application.ExecutablePath);
                Environment.Exit(0);
            }
        }

        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (e.CloseReason == CloseReason.UserClosing)
            {
                if (this.ShowAskDialog2("确定要退出程序吗？", true))
                {
                    Globals.SiemensClient.Close();
                    timer1?.Stop();
                    Application.Exit();

                    Environment.Exit(0);
                }
                else
                {
                    e.Cancel = true;
                }
            }
        }
    }

}
